package io.raf;

import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 演示RandomAccessFile的使用
 * 1.什么是RandomAccessFile
 * 		对于文本的任意位置进行插入或读取内容
 * @author Administrator
 *
 */
public class RandomAccessFileDemo {

	/**
	 * 使用RandomAccessFile
	 * @throws IOException 
	 */
	@Test
	public void demo() throws IOException {
		/*
		 * mode:读取的模式
		 * 		r		只读
		 * 		rw		读写
		 * 		rwd		会直接输出到文件				
		 * 若只是"r"，当文件不存在会抛出FileNotFoundException异常
		 * 模式为"rw"，文件不存在则会创建
		 * 
		 * */
		RandomAccessFile raf = new RandomAccessFile("F:\\a.txt", "rw");
		
		// 文本内容长度
		System.out.println("a.txt的文本的长度：" + raf.length());
		
		// "光标"位置
		System.out.println("a.txt打开后的光标位置：" + raf.getFilePointer());
		
		// 调整"光标"的位置
		raf.seek(5);
		System.out.println("a.txt调整光标后的位置：" + raf.getFilePointer());
		
		// 关闭资源
		raf.close();
	}
	
	
	/**
	 * 使用RandomAccessFile进行读取：光标随着读取内容而改变，当读取所有的东西时，那么光标就在文件的最后
	 * @throws IOException 
	 */
	@Test
	public void demo2() throws IOException {
		RandomAccessFile raf = new RandomAccessFile("F:\\a.txt", "rw");
		
		// 读取:读取到的内容是需要经过ASCLL转换才是真正的内容
//		int content = raf.read();
//		while(content != -1) {
//			System.out.print((char)content);
//			content = raf.read();
//		}
		
		/*
		 * read(byte[]):读取内容，读取到的内容会存储到byte数组中去，返回的length是读取到的长度，当length为-1时表示结束
		 * 
		 */
//		byte[] content = new byte[1024];
//		int length = raf.read(content);
//		while(length != -1) {
//			System.out.println(new String(content));
//			length = raf.read(content);
//		}
		
		/*
		 *	读取一行，返回的是读取到的内容，读取到的内容为null表明读取结束 
		 */
		System.out.println("读取前光标的位置是：" + raf.getFilePointer());
		String content = raf.readLine();
		while (content != null) {
			System.out.println(content);
			content = raf.readLine();
		}
		System.out.println("读取后光标的位置是：" + raf.getFilePointer());
		
		raf.close();
	}
	
	/**
	 * 演示光标对于读取的影响：读取时是以光标的位置开始的，光标前的内容不会被读取，并且读取的过程，光标会一直移动
	 * 
	 * @throws IOException 
	 */
	@Test
	public void demo3() throws IOException {
		RandomAccessFile raf = new RandomAccessFile("F:\\a.txt", "rw");
		
		// 设置光标
		raf.seek(5);
		
		// 读取内容
		String content = raf.readLine();
		while(content != null) {
			System.out.println(content);
			content = raf.readLine();
		}
		raf.close();
	}
	
	/**
	 * 演示写入：写入是在光标开始的位置写入，并且会覆盖写入的位置，简单来说就是插入并修改
	 * @throws IOException 
	 */
	@Test
	public void demo4() throws IOException {
		RandomAccessFile raf = new RandomAccessFile("F:\\a.txt", "rw");

		// write(int)
//		raf.write(65);
		
		// writeChars(字符串)
//		raf.writeChars("今天天气不错");
		
		// 写byte数组的形式 
		raf.write("今天天气不错".getBytes());
		
		// 写带有偏移量的byte数组
		byte[] content = new byte[1024];
		raf.write(content, 0, 10); 
//		raf.write(b, off, len); // b:byte数组	off:偏移量，从byte数组的哪一位开始写		len:写多少位
		
		raf.close();
	}
	
	/**
	 * 今天天气不错->今天123456789天气不错
	 * 实现中间插入
	 * 1.调整光标到今天后面
	 * 2.读取今天后面的内容并保存
	 * 3.调整光标到今天后面
	 * 4.插入123456789
	 * 5.插入暂存的天气不错
	 * @throws IOException 
	 */
	@Test
	public void demo5() throws IOException {
		
		// 用于负责a.txt的读写
		RandomAccessFile raf = new RandomAccessFile("F:\\a.txt", "rw");
		// 负责缓存的读写
		RandomAccessFile rafTemp = new RandomAccessFile(File.createTempFile("temp", null), "rw");
		
		// 1.做缓存
		raf.seek(6);
		int i = raf.read();
		while(i != -1) {
			rafTemp.write(i);
			i = raf.read();
		}
		
		// 2.在a.txt中写入123456789
		String s = "123456789";
		raf.seek(6);
		raf.write(s.getBytes()); 
		
		// 3.将缓存的内容写入到a.txt
		rafTemp.seek(0);
		int i2 = rafTemp.read();
		while(i2 != -1) {
			raf.write(i2);
			i2 = rafTemp.read();
		}
		
		// 关闭资源
		raf.close();
		rafTemp.close();
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}
